#include "tcp_client_poll.h"
#include <stdio.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <poll.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <unistd.h>
#include "socket_tool.h"

void start_client_poll()
{
    puts("启动tcp客户端");

    struct sockaddr_in server_ip;
    bzero(&server_ip, sizeof(server_ip));
    server_ip.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &server_ip.sin_addr.s_addr);
    server_ip.sin_port = htons(12345);

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);

    int conn = connect(sockfd, (struct sockaddr*) &server_ip, sizeof(server_ip));
    if (conn < 0) {
        puts("连接服务器失败");
        exit(-1);
    }
    char *server = sockaddr_to_string(&server_ip);
    printf("连接成功,server=%s\n", server);
    free(server);

    const size_t MAX_FD = 2;
    struct pollfd fds[MAX_FD];
    bzero(fds, sizeof(fds));
    fds[0].fd = sockfd;
    fds[0].events = POLLIN;

    int stdin_fd = fileno(stdin);
    fds[1].fd = stdin_fd;
    fds[1].events = POLLIN;

    const size_t BUF_SIZE = 256;
    char sock_buf[BUF_SIZE], read_buf[BUF_SIZE];
    memset(sock_buf, 0, sizeof(sock_buf));
    memset(read_buf, 0, sizeof(read_buf));

    while (true) {
        int ready_count = poll(&fds, MAX_FD, -1);
        if (ready_count < 0) {
            puts("poll失败");
            exit(-1);
        }
        if (fds[0].revents & POLLIN) {
            // 服务器发来了消息
            int sock_bytes = recv(sockfd, sock_buf, BUF_SIZE, 0);
            if (sock_bytes < -1) {
                puts("连接异常，未能从tcp socket读取到数据，结束运行");
                exit(-1);
            } else if (sock_bytes == 0) {
                puts("收到服务器的FIN，关闭连接，结束运行");
                exit(0);
            }
            printf("服务器说：%s", sock_buf);
            if (strcmp("bye", sock_buf) == 0) {
                puts("服务器发送bye，结束运行");
                exit(0);
            }
        }

        if (fds[1].revents & (POLLIN | POLLERR)) {
            // 标准输入有数据了
            int read_bytes = read(stdin_fd, read_buf, BUF_SIZE);
            if (read_bytes < 0) {
                puts("标准输入错误，结束运行");
                exit(-1);
            } else if (read_bytes == 0) {
                // 按下了ctrl c
                puts("结束运行");
                return;
            }
            // 发送给服务器
            send(sockfd, read_buf, strlen(read_buf) + 1, 0);
        }
    }

}